/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.siseventos.managed;

import br.siseventos.dao.da.EventoDAO;
import br.siseventos.dao.da.PublicoDAO;
import br.siseventos.dao.da.TipoEventoDAO;
import br.siseventos.model.TbEvento;
import br.siseventos.model.TbPublico;
import br.siseventos.model.TdTipoEvento;
import br.siseventos.service.EventoService;
import br.siseventos.view.util.CallbackHelper;
import br.siseventos.view.util.MessageHelper;
import br.siseventos.view.util.ScheduleEventConverter;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.event.ActionEvent;
import org.joda.time.DateTime;
import org.primefaces.event.DateSelectEvent;
import org.primefaces.event.ScheduleEntrySelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.LazyScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

@ManagedBean(name = "eventoBean")
@SessionScoped
public class EventoBean implements Serializable {

    private static long serialVersionUID = 1L;
    // Campos
    private String nome = null;
    private String descricao = null;
    private Date dataInicio = null;
    private Date dataTermino = null;
    private TdTipoEvento tipoEventoSelecionado = null;
    private List<TdTipoEvento> tiposEvento = null;
    private List<TbPublico> lstPublicoAlvo = null;
    private List<TbPublico> publicosAlvo = null;
    private ScheduleModel eventos = null;
    private ScheduleEvent evento = new DefaultScheduleEvent();
    
    // DAOs
    private static EventoDAO daoEvento = null;
    private static TipoEventoDAO daoTipoEvento = null;
    private static PublicoDAO daoPublico = null;

    // Construtor
    public EventoBean() {

        // Inicializando as DAOs
        setDaoEvento(new EventoDAO());
        setDaoTipoEvento(new TipoEventoDAO());
        setDaoPublico(new PublicoDAO());

        // Inicializando as listas
        tiposEvento = daoTipoEvento.consultarTodos();

        // Implementando o esquema de Lazy Loading de eventos
        eventos = new LazyScheduleModel() {

            @Override
            public void loadEvents(Date start, Date end) {
                // Limpando os eventos do frame
                clear();

                // Carregando os eventos do frame
                List lstEventos = daoEvento.consultarTodos(start, end);
                List<ScheduleEvent> lst = ScheduleEventConverter.convertToScheduleEvents(lstEventos);
                for (ScheduleEvent e : lst) {
                    addEvent(e);
                }
            }
        };
    }

    // Getters e Setters
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public static void setSerialVersionUID(long aSerialVersionUID) {
        serialVersionUID = aSerialVersionUID;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public Date getDataInicio() {
        return dataInicio;
    }

    public void setDataInicio(Date dataInicio) {
        this.dataInicio = dataInicio;
    }

    public Date getDataTermino() {
        return dataTermino;
    }

    public void setDataTermino(Date dataTermino) {
        this.dataTermino = dataTermino;
    }

    public TdTipoEvento getTipoEventoSelecionado() {
        return tipoEventoSelecionado;
    }

    public void setTipoEventoSelecionado(TdTipoEvento tipoEventoSelecionado) {
        this.tipoEventoSelecionado = tipoEventoSelecionado;
    }

    public List<TdTipoEvento> getTiposEvento() {
        return tiposEvento;
    }

    public void setTiposEvento(List<TdTipoEvento> lstTipoEvento) {
        this.tiposEvento = lstTipoEvento;
    }

    public List<TbPublico> getLstPublicoAlvo() {
        return lstPublicoAlvo;
    }

    public void setLstPublicoAlvo(List<TbPublico> lstPublicoAlvo) {
        this.lstPublicoAlvo = lstPublicoAlvo;
    }

    public ScheduleEvent getEvento() {
        return evento;
    }

    public void setEvento(ScheduleEvent evento) {
        this.evento = evento;
    }

    public static EventoDAO getDaoEvento() {
        return daoEvento;
    }

    public static void setDaoEvento(EventoDAO aDaoEvento) {
        daoEvento = aDaoEvento;
    }

    public static TipoEventoDAO getDaoTipoEvento() {
        return daoTipoEvento;
    }

    public static void setDaoTipoEvento(TipoEventoDAO aDaoTipoEvento) {
        daoTipoEvento = aDaoTipoEvento;
    }

    public static PublicoDAO getDaoPublico() {
        return daoPublico;
    }

    public static void setDaoPublico(PublicoDAO aDaoPublico) {
        daoPublico = aDaoPublico;
    }

    public ScheduleModel getEventos() {
        return eventos;
    }

    public void setEventos(ScheduleModel eventos) {
        this.eventos = eventos;
    }

    public List<TbPublico> getPublicosAlvo() {
        if (publicosAlvo == null) {
            publicosAlvo = daoPublico.consultarTodos();
        }
        return publicosAlvo;
    }
    // Implementação da interface Converter

    public Converter getConversorTipoEvento() {
        return new Converter() {

            public Object getAsObject(FacesContext context, UIComponent component, String value) {
                // Transformar string em objeto
                TdTipoEvento e = null;

                try {
                    e = getDaoTipoEvento().consultarPorIdt(Integer.parseInt(value));
                } catch (NumberFormatException ex) {
                }
                return e;

            }

            @Override
            public String getAsString(FacesContext context, UIComponent component, Object value) {
                // Transformar objeto em string
                String r = null;
                if (value instanceof TdTipoEvento) {
                    r = ((TdTipoEvento) value).getIdtTipoEvento().toString();
                }
                return r;
            }
        };
    }
    // Actions e Listener

    public void cadastrarEvento(ActionEvent e) {

        try {
            EventoService svc = new EventoService();
            TbEvento ev = new TbEvento(getTipoEventoSelecionado(), getNome(),
                    getDescricao(), getDataInicio(), getDataTermino(), '0', new Date());

            // Cadastrando o evento sem os itens de avaliação
            svc.incluir(ev, lstPublicoAlvo, null);
            MessageHelper.showGlobalMessage("Evento cadastrado com sucesso!", FacesMessage.SEVERITY_INFO);

        } catch (Exception ex) {
            MessageHelper.showGlobalMessage("Erro ao cadastrar evento!", FacesMessage.SEVERITY_ERROR);
        }


        // Setando o parametro de callback
        CallbackHelper.addCallback(new HashMap<String, Object>() {

            {
                put("salvo", true);
                put("limpar", true);
            }
        });

    }

    // Excluir o evento selecionado
    public void excluirEvento(ActionEvent e) {

        try {
            // Buscando o evento a ser excluído
            TbEvento ev = daoEvento.consultarPorNmeExato(getEvento().getTitle());
            if (ev.getIdtEvento() == null || ev.getIdtEvento() < 0) {
                throw new Exception("Erro de ID");
            }
            // Excluindo evento
            daoEvento.excluir(ev.getIdtEvento());
            MessageHelper.showGlobalMessage("Evento excluído com sucesso!", FacesMessage.SEVERITY_INFO);
        } catch (Exception ex) {
            MessageHelper.showGlobalMessage("Erro ao excluir evento!", FacesMessage.SEVERITY_ERROR);
        }

    }

    public void dataMinAlterada(DateSelectEvent e) {
        DateTime dt = new DateTime(e.getDate());
        Date toCompare = (getDataTermino() != null) ? getDataTermino() : dt.plusDays(1).toDate();
        if (e.getDate().after(toCompare)) {
            MessageHelper.showGlobalMessage("Erro!", FacesMessage.SEVERITY_INFO);
        } else {
            MessageHelper.showGlobalMessage("Data Inicio: " + e.getDate(), FacesMessage.SEVERITY_INFO);
        }
    }

    public void dataMaxAlterada(DateSelectEvent e) {
        MessageHelper.showGlobalMessage("Data Termino" + e.getDate(), FacesMessage.SEVERITY_INFO);
    }

    public void eventoSelecionado(ScheduleEntrySelectEvent e) {
        evento = e.getScheduleEvent();
        MessageHelper.showGlobalMessage("Evento: " + evento.getTitle() + " " + evento.getStartDate().toString(), null);
    }
    
    public void dataSelecionada(DateSelectEvent e){
        setDataInicio(e.getDate());
        setDataTermino(e.getDate());
        MessageHelper.showGlobalMessage(":)", FacesMessage.SEVERITY_INFO);
    }
    // Util
}
